package com.cch.datageniebackendmaster.aop;

import cn.hutool.core.date.StopWatch;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * 请求响应日志拦截器
 *
 * @author cch
 */
@Aspect
@Component
@Slf4j
public class LogInterceptor {

    // 注意：这里拦截的是 controller 包下的所有 public 方法
    @Around("execution(* com.cch.datageniebackendmaster.controller.*.*(..))")
    public Object logInterceptor(ProceedingJoinPoint joinPoint) throws Throwable {
        // 计时开始
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 获取请求对象
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
        // 生成唯一请求 id
        String requestId = UUID.randomUUID().toString();
        // 获取请求路径
        String url = httpServletRequest.getRequestURI();
        // 获取请求参数
        Object[] args = joinPoint.getArgs();
        String requestArgs = JSONUtil.toJsonStr(args[0]);
        // 获取请求ip
        String remoteHost = httpServletRequest.getRemoteHost();
        // 打印请求日志
        log.info("请求开始，请求id：{}，请求路径：{}，请求参数：{}，请求ip：{}", requestId, url, requestArgs, remoteHost);
        // 执行原方法
        Object result = joinPoint.proceed();
        // 计时结束
        stopWatch.stop();
        // 打印响应日志
        log.info("请求结束，请求id：{}，响应结果：{}，耗时：{}ms", requestId, result, stopWatch.getTotalTimeMillis());
        return result;
    }

}
